package com.itheima.service.impl;

import com.itheima.common.constant.MessageConstant;
import com.itheima.common.exception.AuthenticationFailedException;
import com.itheima.common.exception.DataNotFoundException;
import com.itheima.common.exception.DuplicateDataException;
import com.itheima.common.exception.NoSpaceException;
import com.itheima.mapper.MemberMapper;
import com.itheima.mapper.OrderMapper;
import com.itheima.mapper.OrderSettingMapper;
import com.itheima.mapper.SetmealMapper;
import com.itheima.pojo.*;
import com.itheima.service.OrderService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDate;
import java.util.Objects;

@Service
public class OrderServiceImpl implements OrderService {

    @Autowired
    private OrderMapper orderMapper;
    @Autowired
    private RedisTemplate<String, String> redisTemplate;
    @Autowired
    private OrderSettingMapper orderSettingMapper;
    @Autowired
    private MemberMapper memberMapper;
    @Autowired
    private SetmealMapper setmealMapper;

    /**
     * 添加预约信息
     *
     * @param orderDTO
     * @return
     */
    @Override
    @Transactional
    public Integer addOrder(OrderDTO orderDTO) {
        // 判断验证码是否正确
        String phone = orderDTO.getTelephone();
        String code = redisTemplate.opsForValue().get(phone + "Order");
        // 设置0000为后门,方便验证功能
        if (!Objects.equals(code, orderDTO.getValidateCode()) && !"0000".equals(orderDTO.getValidateCode())) {
            throw new AuthenticationFailedException(MessageConstant.VALIDATECODE_ERROR);
        }
        // 移除redis缓存
        redisTemplate.delete(phone + "Order");
        // 查询是否还有预约空间
        OrderSetting orderSetting = orderSettingMapper.selectByDate(orderDTO.getOrderDate());
        if (orderSetting == null || orderSetting.getNumber() <= orderSetting.getReservations()) {
            throw new NoSpaceException(MessageConstant.ORDER_FULL);
        }
        // 根据IDCard 查询用户会员信息,如果不存在则自动注册
        Member member = memberMapper.selectByIDCard(orderDTO.getIdCard());
        if (member == null) {
            member = new Member();
            member.setName(orderDTO.getName());
            member.setSex(orderDTO.getSex());
            member.setIdCard(orderDTO.getIdCard());
            member.setPhoneNumber(orderDTO.getTelephone());
            member.setRegTime(LocalDate.now());
            memberMapper.insert(member);
        }
        // 判断当前会员当日是否已经预约了同一个套餐
        Integer count = orderMapper.countByMemberIdAndDateWithSetmeal(member.getId(), orderDTO.getOrderDate(), orderDTO.getSetmealId());
        if (count > 0) {
            // 今日已经有了预约,预约失败
            throw new DuplicateDataException(MessageConstant.ORDERSETTING_FAIL);
        }
        // 封装预约信息
        Order order = new Order();
        BeanUtils.copyProperties(orderDTO, order);
        order.setMemberId(member.getId());
        order.setOrderType(Order.ORDERTYPE_WEIXIN);
        order.setOrderStatus(Order.ORDERSTATUS_NO);
        // 添加预约信息
        orderMapper.insert(order);
        // 修改预约人数
        orderSetting.setReservations(orderSetting.getReservations() + 1);
        orderSettingMapper.update(orderSetting);
        return order.getId();
    }

    /**
     * 根据ID查询预约信息
     * @param id
     * @return
     */
    @Override
    public OrderVO findById(Integer id) {
        // 查询预约信息
        Order order = orderMapper.selectById(id);
        if (order == null || order.getSetmealId() == null || order.getMemberId() == null) {
            throw new DataNotFoundException(MessageConstant.QUERY_ORDER_FAIL);
        }
        // 查询会员信息
        Member member = memberMapper.selectById(order.getMemberId());
        // 查询套餐信息
        Setmeal setmeal = setmealMapper.selectById(order.getSetmealId());
        return new OrderVO(member.getName(), setmeal.getName(), order.getOrderDate(), order.getOrderType());
    }
}
